package io.gitee.guoguoleo.helper;

import cn.hutool.core.collection.ListUtil;
import io.gitee.guoguoleo.chain.QueryChain;
import io.gitee.guoguoleo.chain.UpdateChain;
import io.gitee.guoguoleo.wrapper.QueryWrapper;
import io.gitee.guoguoleo.wrapper.UpdateWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Slf4j
@Component
public class JokerHelper {

    @Resource
    private JdbcTemplate jdbcTemplate;

    public <T> QueryChain<T> lambdaQuery(Class<T> clazz) {
        return new QueryChain<>(clazz, this.jdbcTemplate);
    }

    public <T> T getById(Class<T> clazz, Serializable id) {
        return this.lambdaQuery(clazz).getById(id);
    }

    public <T> List<T> listByIds(Class<T> clazz, Collection<? extends Serializable> ids) {
        return this.lambdaQuery(clazz).listByIds(ids);
    }

    public <T> List<T> listByIds(Class<T> clazz, Serializable... ids) {
        return this.listByIds(clazz, ListUtil.toList(ids));
    }


    public <T> T getOne(Class<T> clazz, QueryWrapper<T> queryWrapper) {
        return this.lambdaQuery(clazz).one(queryWrapper);
    }

    public <T> List<T> getList(Class<T> clazz, QueryWrapper<T> queryWrapper) {
        return this.lambdaQuery(clazz).list(queryWrapper);
    }


    public <T> UpdateChain<T> lambdaUpdate(Class<T> clazz) {
        return new UpdateChain<>(clazz, this.jdbcTemplate);
    }


    public <T> boolean save(Class<T> clazz, T entity) {
        return this.lambdaUpdate(clazz).save(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean saveBatch(Class<T> clazz, List<T> entityList) {
        return this.lambdaUpdate(clazz).saveBatch(entityList);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean saveBatch(Class<T> clazz, List<T> entityList, long batchSize) {
        return this.lambdaUpdate(clazz).saveBatch(entityList, batchSize);
    }


    public <T> boolean updateById(Class<T> clazz, T entity) {
        return this.lambdaUpdate(clazz).updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean updateBatchById(Class<T> clazz, List<T> entityList) {
        return this.lambdaUpdate(clazz).updateBatchById(entityList);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean updateBatchById(Class<T> clazz, List<T> entityList, long batchSize) {
        return this.lambdaUpdate(clazz).updateBatchById(entityList, batchSize);
    }


    public <T> boolean saveOrUpdate(Class<T> clazz, T entity) {
        return this.lambdaUpdate(clazz).saveOrUpdate(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean saveOrUpdateBatch(Class<T> clazz, List<T> entityList, long batchSize) {
        return this.lambdaUpdate(clazz).saveOrUpdateBatch(entityList,batchSize);
    }

    @Transactional(rollbackFor = Exception.class)
    public <T> boolean saveOrUpdateBatch(Class<T> clazz, List<T> entityList) {
        return this.lambdaUpdate(clazz).saveOrUpdateBatch(entityList);
    }

    public <T> boolean removeById(Class<T> clazz, Serializable id) {
        return this.lambdaUpdate(clazz).removeById(id);
    }

    public <T> boolean removeByIds(Class<T> clazz, Collection<? extends Serializable> ids) {
        return this.lambdaUpdate(clazz).removeByIds(ids);
    }

    public <T> boolean removeByIds(Class<T> clazz, Serializable... ids) {
        return this.lambdaUpdate(clazz).removeByIds(ids);
    }

    public <T> boolean update(Class<T> clazz, UpdateWrapper<T> updateWrapper) {
        return this.lambdaUpdate(clazz).update(updateWrapper);
    }

    public <T> boolean update(Class<T> clazz, UpdateWrapper<T> updateWrapper, T entity) {
        return this.lambdaUpdate(clazz).update(updateWrapper, entity);
    }

    public <T> boolean remove(Class<T> clazz, UpdateWrapper<T> updateWrapper) {
        return this.lambdaUpdate(clazz).remove(updateWrapper);
    }

}
